package com.fingard.dsp.bank.directbank.boc01;

import java.io.File;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directbank.bankInterface.IElecBillQuery;
import com.fingard.dsp.bank.reqrespobj.elecbillquery.*;
import com.fingard.dsp.bank.reqrespobj.elecbillquery.detail.*;
import com.fingard.text.StringHelper;
import com.fingard.util.DateHelper;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

import static com.fingard.text.StringHelper.getFileParentDir;
import static com.fingard.text.StringHelper.trimEndFileSp;

public class BOC01ElecBill extends BOC01Base implements IElecBillQuery {
    public RetAtsB001OperBillQry D_OperBill_Thread(ReqB001OperBillQry reqB001OperBillQry) throws Exception {
        //因为如果查询5000笔，需要查询100次，每次请求到下次请求之间等待银行响应的时间不可改变（看实施提供日志一般在3~4s等待响应）
        //1.第一次请求不使用线程，得到查询的总笔数
        //2.之后每次请求都放入线程池中，同时进行查询，由此达到减少查询时间的目的
        final ReqB001OperBillQry query = reqB001OperBillQry;
        final RetAtsB001OperBillQry retAts = new RetAtsB001OperBillQry(query.reqHeader);
        final List<RetAtsB001OperBillQryDetail> detailList = new ArrayList<RetAtsB001OperBillQryDetail>();
        String respCode = "";
        String respInfo = "";
        retAts.respCode = "0";
        retAts.respInfo = "";
        retAts.writeBefore();
        try {
            while (query.readRecord()) {
                //回购贴现申请不支持
                if ("11".equals(query.detail.busiType)) {
                    retAts.writeRespCode("0");
                    retAts.writeRespInfo("不支持回购贴现申请");
                    retAts.writeEnd();
                    return retAts;
                }
                if ("2".equals(query.detail.overdueFlag)) {
                    retAts.writeRespCode("0");
                    retAts.writeRespInfo("逾期票据不查询");
                    retAts.writeEnd();
                    return retAts;
                }

                int readNum = 1;//默认查询位置
                int totalNum = 0;//总查询数
                int respNum = 0;//实际返回数

                ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);//创建一个固定长度为3的线程池

                final Map<String, Object> paramsMap = new HashMap<String, Object>();
                paramsMap.put("totalNum", totalNum);
                paramsMap.put("readNum", readNum);
                paramsMap.put("respNum", respNum);
                paramsMap.put("respCode", respCode);
                paramsMap.put("respInfo", respInfo);

                //第一次查询取得总笔数
                first_OperBill_Req(query, detailList, paramsMap);
                totalNum = Integer.parseInt(paramsMap.get("totalNum").toString());
                readNum = Integer.parseInt(paramsMap.get("readNum").toString());

                for (; readNum <= totalNum; readNum += 50) {//根据第一次返回的总笔数来判断是否发送请求
                    boolean isNeedWait = isNeedWaitFiveS();//是否需要和前一次请求保持5秒的间隔
                    if (isNeedWait) {
                        Thread.sleep(5000);//前置机限制，每次发送请求要间隔5秒
                    }
                    final Map<String, Object> tmpParamsMap = new HashMap<String, Object>();
                    tmpParamsMap.put("respCode", paramsMap.get("respCode").toString());
                    tmpParamsMap.put("respInfo", paramsMap.get("respInfo").toString());
                    tmpParamsMap.put("readNum", readNum);
                    fixedThreadPool.execute(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                first_OperBill_Req(query, detailList, tmpParamsMap);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    });
                }
                // 启动一次顺序关闭，执行以前提交的任务，但不接受新任务。
                fixedThreadPool.shutdown();

                try {
                    // 请求关闭、发生超时或者当前线程中断，无论哪一个首先发生之后，都将导致阻塞，直到所有任务完成执行
                    // 设置最长等待10秒
                    int timeout = 10;
                    String timeOutTime = getBankConfig().getValueAsString("elecThreadPoolWaitTime");
                    if (!StringHelper.isNullOrEmpty(timeOutTime)) {
                        timeout = Integer.parseInt(timeOutTime);
                    }
                    WriteBankLogLn("线程超时时间为" + timeout);
                    fixedThreadPool.awaitTermination(timeout, TimeUnit.SECONDS);
                } catch (InterruptedException e) {
                    //
                    e.printStackTrace();
                }

                //以下主线程继续执行
                for (int i = 0; i < detailList.size(); i++) {
                    retAts.writeDetail(detailList.get(i));
                }
                WriteBankLogLn("请求线程处理完毕！");
                respCode = paramsMap.get("respCode").toString();
                respInfo = paramsMap.get("respInfo").toString();
            }
            if ("-1".equals(respCode)) {
                RetAtsB001OperBillQry errRetAts = new RetAtsB001OperBillQry(query.reqHeader);
                errRetAts.respCode = "-1";
                errRetAts.respInfo = respInfo;
                errRetAts.writeBefore();
                errRetAts.writeEnd();
                return errRetAts;
            }
        } catch (Exception e) {
            RetAtsB001OperBillQry errRetAts = new RetAtsB001OperBillQry(query.reqHeader);
            errRetAts.respCode = "-1";
            errRetAts.respInfo = e.getMessage();
            errRetAts.writeBefore();
            errRetAts.writeEnd();
            return errRetAts;
        }
        retAts.writeEnd();
        return retAts;
    }

    public void first_OperBill_Req(ReqB001OperBillQry query, List<RetAtsB001OperBillQryDetail> detailList, Map<String, Object> paramsMap) throws Exception {
        int totalNum = 0;//总查询数
        int readNum = Integer.parseInt(paramsMap.get("readNum").toString());//默认查询位置
        int respNum = 0;//每次请求实际返回数
        String respCode = "";
        String respInfo = "";

        BOC01Header bankHeader = new BOC01Header();
        bankHeader.trncod = "b2e0102";//交易代码
        bankHeader.trnid = getQryTransID();//报文编号 字母数字串 0-12位
        XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
        String QueryType = "";
        String actNum = "";
        String billType = "";
        writeCommonHeader(xmlWriter, bankHeader);
        xmlWriter.writeStartElement("trn-b2e0102-rq");
        xmlWriter.writeStartElement("b2e0102-rq");
        xmlWriter.writeElementString("ibknum", "");
        actNum = query.detail.actNum;
        billType = "1".equals(query.detail.billType) ? "AC01" : "AC02";
        xmlWriter.writeElementString("actacn", query.detail.actNum);
        xmlWriter.writeElementString("payeeactn", "");
        QueryType = DealQueryType(query);
        xmlWriter.writeElementString("querytype", QueryType);
        xmlWriter.writeElementString("acttyp", "");
        xmlWriter.writeElementString("drafttype", billType);
        xmlWriter.writeElementString("draweename", "");
        xmlWriter.writeElementString("acceptorname", "");
        xmlWriter.writeElementString("toname", "");
        xmlWriter.writeElementString("draftno", query.detail.billNo);
        xmlWriter.writeStartElement("datescope");
        xmlWriter.writeElementString("from", "");
        xmlWriter.writeElementString("to", "");
        xmlWriter.writeEndElement();
        xmlWriter.writeStartElement("amountscope");
        xmlWriter.writeElementString("from", "");
        xmlWriter.writeElementString("to", "");
        xmlWriter.writeEndElement();
        xmlWriter.writeElementString("begnum", readNum + "");//起始数
        xmlWriter.writeElementString("recnum", "50");//每页内容，固定50
        xmlWriter.writeEndDocument();
        //是否需要和前一次请求保持5秒的间隔
//        boolean isNeedWait = isNeedWaitFiveS();
//        if (isNeedWait) {
//            if (bankFront.lastVisitTime != null) {
//                long timeSpan = -bankFront.lastVisitTime.getTime() + new Date().getTime();
//                if (timeSpan < 5000l) {
//                    long sleepMils = 5000l - timeSpan;
//                    this.WriteBankLogLn2("sleep(" + sleepMils + ")");
//                    Thread.sleep(5000l - timeSpan);
//                }
//            }
//        }

        String[] retStrArr = sendToBank(xmlWriter.toXmlString());

        if (retStrArr[0].length() == 0) {
            StringBuilder tmpSbMsg = new StringBuilder();
            XmlTextReader tmpBkReader = loadBankRespXmlReader(retStrArr[1], tmpSbMsg);
            if (tmpBkReader != null) {
                String tmpRetCode = tmpBkReader.getFirstText("/bocb2e/trans/trn-b2e0102-rs/status/rspcod");
                String tmpRetInfo = tmpBkReader.getFirstText("/bocb2e/trans/trn-b2e0102-rs/status/rspmsg");
                String totalnum = tmpBkReader.getFirstText("/bocb2e/trans/trn-b2e0102-rs/totalnum");//查询总数
//                if ("B001".equals(tmpRetCode)) {//当返回B001时，表示查询完毕，不需要进行下一页查询
//                    WriteBankLogLn("来过pageFlag");
//                    pageFlag = false;
//                }
                if (StringHelper.hasAnyChar(totalnum)) {
                    totalNum = Integer.parseInt(totalnum);
                }
                //int count = 0;
                if (isActiveRetCode(tmpRetCode)) {
                    while (tmpBkReader.read("/bocb2e/trans/trn-b2e0102-rs/b2e0102-rs")) {
                        String EachRespCode = tmpBkReader.readedXElement.getSingleText("status/rspcod");
                        String EachRespInfo = tmpBkReader.readedXElement.getSingleText("status/rspmsg");
                        if (bankRetRightCode.equals(EachRespCode)) {
                            respNum++;
                            //count++;
                            RetAtsB001OperBillQryDetail detail = new RetAtsB001OperBillQryDetail();
                            detail.drawAct = tmpBkReader.readedXElement.getSingleText("draweeacn");//出票人账号
                            detail.drawName = tmpBkReader.readedXElement.getSingleText("draweename");
                            detail.drawCode = tmpBkReader.readedXElement.getSingleText("cliorg");
                            detail.payeeAct = tmpBkReader.readedXElement.getSingleText("toacn");//收票人账号
                            detail.payeeName = tmpBkReader.readedXElement.getSingleText("toname");
                            detail.accpAct = tmpBkReader.readedXElement.getSingleText("acceptoracn");
                            detail.accpName = tmpBkReader.readedXElement.getSingleText("acceptorname");//承兑人
                            detail.billAmt = tmpBkReader.readedXElement.getSingleText("amount");
                            detail.billNo = tmpBkReader.readedXElement.getSingleText("draftno");
                            detail.issDate = DateHelper.convertD8toD10(tmpBkReader.readedXElement.getSingleText("date"));
                            detail.dueDate = DateHelper.convertD8toD10(tmpBkReader.readedXElement.getSingleText("duedate"));
                            detail.applyName = tmpBkReader.readedXElement.getSingleText("applyname");
                            //收票签收
                            if ("A8".equals(QueryType) && StringHelper.isNullOrEmpty(detail.applyName)) {
                                detail.applyName = detail.drawName;
                            }
                            detail.mustPay = "1";
                            detail.discRate = tmpBkReader.readedXElement.getSingleText("rdsrat");
                            detail.recourseAmt = tmpBkReader.readedXElement.getSingleText("tramt");
                            detail.billStatus = tmpBkReader.readedXElement.getSingleTextByIndex("status", 1);
                            detail.billType = "AC01".equals(tmpBkReader.readedXElement.getSingleText("drafttype")) ? "EM001" : "EM002";

                            detail.busiNo = tmpBkReader.readedXElement.getSingleText("msgseq");
                            if ("A8".equals(QueryType) || "C3".equals(QueryType)) {
                                boolean isQueryTransFlag = getBankConfig().getValueAsBool("isQueryTransFlag");
                                if (isQueryTransFlag) {
                                    String tranFlag = getTransferflg(actNum, detail.billNo, detail.busiNo,
                                            QueryType);
                                    if (StringHelper.hasAnyChar(tranFlag)) {
                                        detail.transFlag = "EM00".equals(tranFlag) ? "1" : "0";
                                    }
                                }
                            }
                            detailList.add(detail);
                            readNum++;//遍历一遍数据，查询起始数+1
                        } else {
                            respCode = "0";
                            respInfo = EachRespInfo;
                            break;
                        }
                    }
                } else {
                    respCode = "-1";
                    respInfo = tmpRetInfo;
                }
            } else {
                respCode = "-1";
                respInfo = tmpSbMsg.toString();
            }
        } else {
            respCode = "-1";
            respInfo = retStrArr[1];
        }
        WriteBankLogLn("请求起始值：" + Integer.parseInt(paramsMap.get("readNum").toString()) + ";请求实际查询数：" + respNum);

        paramsMap.put("totalNum", totalNum);
        paramsMap.put("readNum", readNum);
        paramsMap.put("respCode", respCode);
        paramsMap.put("respInfo", respInfo);

    }

    /**
     * 单线程查询
     * @param query
     * @return
     * @throws Exception
     */
    private RetAtsB001OperBillQry singleThreadQuery(ReqB001OperBillQry query) throws Exception {
        RetAtsB001OperBillQry retAts = new RetAtsB001OperBillQry(query.reqHeader);
        String respCode = "";
        String respInfo = "";
        retAts.respCode = "0";
        retAts.respInfo = "";
        retAts.writeBefore();
        while (query.readRecord()) {
            boolean pageFlag = true;//是否需要进行下一页查询
            int readNum = 1;//默认查询位置
            int totalNum = 0;//总查询数
            int respNum = 0;//实际返回数
            while (pageFlag) {
                BOC01Header bankHeader = new BOC01Header();
                bankHeader.trncod = "b2e0102";//交易代码
                bankHeader.trnid = getQryTransID();//报文编号 字母数字串 0-12位
                XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
                String QueryType = "";
                String actNum = "";
                String billType = "";
                writeCommonHeader(xmlWriter, bankHeader);
                xmlWriter.writeStartElement("trn-b2e0102-rq");

                //回购贴现申请不支持
                if ("11".equals(query.detail.busiType)) {
                    retAts.writeRespCode("0");
                    retAts.writeRespInfo("不支持回购贴现申请");
                    retAts.writeEnd();
                    return retAts;
                }
                if ("2".equals(query.detail.overdueFlag)) {
                    retAts.writeRespCode("0");
                    retAts.writeRespInfo("逾期票据不查询");
                    retAts.writeEnd();
                    return retAts;
                }
                xmlWriter.writeStartElement("b2e0102-rq");
                xmlWriter.writeElementString("ibknum", "");
                actNum = query.detail.actNum;
                billType = "1".equals(query.detail.billType) ? "AC01" : "AC02";
                xmlWriter.writeElementString("actacn", query.detail.actNum);
                xmlWriter.writeElementString("payeeactn", "");
                QueryType = DealQueryType(query);
                xmlWriter.writeElementString("querytype", QueryType);
                xmlWriter.writeElementString("acttyp", "");
                xmlWriter.writeElementString("drafttype", billType);
                xmlWriter.writeElementString("draweename", "");
                xmlWriter.writeElementString("acceptorname", "");
                xmlWriter.writeElementString("toname", "");
                xmlWriter.writeElementString("draftno", query.detail.billNo);
                xmlWriter.writeStartElement("datescope");
                xmlWriter.writeElementString("from", "");
                xmlWriter.writeElementString("to", "");
                xmlWriter.writeEndElement();
                xmlWriter.writeStartElement("amountscope");
                xmlWriter.writeElementString("from", "");
                xmlWriter.writeElementString("to", "");
                xmlWriter.writeEndElement();
                xmlWriter.writeElementString("begnum", readNum + "");//起始数
                xmlWriter.writeElementString("recnum", "50");//每页内容，固定50
                xmlWriter.writeEndDocument();
                //是否需要和前一次请求保持5秒的间隔
                boolean isNeedWait = isNeedWaitFiveS();
                if (isNeedWait) {
                    if (bankFront.lastVisitTime != null) {
                        long timeSpan = -bankFront.lastVisitTime.getTime() + new Date().getTime();
                        if (timeSpan < 5000l) {
                            long sleepMils = 5000l - timeSpan;
                            this.WriteBankLogLn2("sleep(" + sleepMils + ")");
                            Thread.sleep(5000l - timeSpan);
                        }
                    }
                }
                String[] retStrArr = sendToBank(xmlWriter.toXmlString());
                if (retStrArr[0].length() == 0) {
                    StringBuilder tmpSbMsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(retStrArr[1], tmpSbMsg);
                    if (tmpBkReader != null) {
                        String tmpRetCode = tmpBkReader.getFirstText("/bocb2e/trans/trn-b2e0102-rs/status/rspcod");
                        String tmpRetInfo = tmpBkReader.getFirstText("/bocb2e/trans/trn-b2e0102-rs/status/rspmsg");
                        String totalnum = tmpBkReader.getFirstText("/bocb2e/trans/trn-b2e0102-rs/totalnum");//查询总数
                        if ("B001".equals(tmpRetCode)) {//当返回B001时，表示查询完毕，不需要进行下一页查询
                            WriteBankLogLn("来过pageFlag");
                            pageFlag = false;
                        }
                        if (StringHelper.hasAnyChar(totalnum)) {
                            totalNum = Integer.parseInt(totalnum);
                        }
                        //int count = 0;
                        if (isActiveRetCode(tmpRetCode)) {
                            while (tmpBkReader.read("/bocb2e/trans/trn-b2e0102-rs/b2e0102-rs")) {
                                String EachRespCode = tmpBkReader.readedXElement.getSingleText("status/rspcod");
                                String EachRespInfo = tmpBkReader.readedXElement.getSingleText("status/rspmsg");
                                if (bankRetRightCode.equals(EachRespCode)) {
                                    respNum++;
                                    //count++;
                                    RetAtsB001OperBillQryDetail detail = new RetAtsB001OperBillQryDetail();
                                    detail.drawAct = tmpBkReader.readedXElement.getSingleText("draweeacn");//出票人账号
                                    detail.drawName = tmpBkReader.readedXElement.getSingleText("draweename");
                                    detail.drawCode = tmpBkReader.readedXElement.getSingleText("cliorg");
                                    detail.payeeAct = tmpBkReader.readedXElement.getSingleText("toacn");//收票人账号
                                    detail.payeeName = tmpBkReader.readedXElement.getSingleText("toname");
                                    detail.accpAct = tmpBkReader.readedXElement.getSingleText("acceptoracn");
                                    detail.accpName = tmpBkReader.readedXElement.getSingleText("acceptorname");//承兑人
                                    detail.billAmt = tmpBkReader.readedXElement.getSingleText("amount");
                                    detail.billNo = tmpBkReader.readedXElement.getSingleText("draftno");
                                    detail.issDate = DateHelper.convertD8toD10(tmpBkReader.readedXElement.getSingleText("date"));
                                    detail.dueDate = DateHelper.convertD8toD10(tmpBkReader.readedXElement.getSingleText("duedate"));
                                    detail.applyName = tmpBkReader.readedXElement.getSingleText("applyname");
                                    //收票签收
                                    if ("A8".equals(QueryType) && StringHelper.isNullOrEmpty(detail.applyName)) {
                                        detail.applyName = detail.drawName;
                                    }
                                    detail.mustPay = "1";
                                    detail.discRate = tmpBkReader.readedXElement.getSingleText("rdsrat");
                                    detail.recourseAmt = tmpBkReader.readedXElement.getSingleText("tramt");
                                    detail.billStatus = tmpBkReader.readedXElement.getSingleTextByIndex("status", 1);
                                    detail.billType = "AC01".equals(tmpBkReader.readedXElement.getSingleText("drafttype")) ? "EM001" : "EM002";

                                    detail.busiNo = tmpBkReader.readedXElement.getSingleText("msgseq");
                                    if ("A8".equals(QueryType) || "C3".equals(QueryType)) {
                                        boolean isQueryTransFlag = getBankConfig().getValueAsBool("isQueryTransFlag");
                                        if (isQueryTransFlag) {
                                            String tranFlag = getTransferflg(actNum, detail.billNo, detail.busiNo,
                                                    QueryType);
                                            if (StringHelper.hasAnyChar(tranFlag)) {
                                                detail.transFlag = "EM00".equals(tranFlag) ? "1" : "0";
                                            }
                                        }
                                    }
                                    retAts.writeDetail(detail);
                                    readNum++;//遍历一遍数据，查询起始数+1
                                    /*if (count == page && count <= 50) {
                                        retAts.writeRespCode("0");
                                        retAts.writeRespInfo("");
                                    }*/
                                } else {
                                    respCode = "0";
                                    respInfo = EachRespInfo;
                                    break;
                                }
                            }
                            /*if (!StringHelper.isNullOrEmpty(totalPage) && Integer.parseInt(totalPage) > 50) {
                                int pageNum = Integer.parseInt(totalPage) / 50 + (Integer.parseInt(totalPage) % 50 == 0 ? 0 : 1);
                                for (int i = 2; i <= pageNum; i++) {
                                    retAts = queryLoop(query, (i - 1) * 50 + 1, retAts, QueryType, actNum, billType);
                                }
                                retAts.writeRespCode("0");
                                retAts.writeRespInfo("");
                            }*/
                        } else {
                            respCode = "-1";
                            respInfo = tmpRetInfo;
                            break;
                        }
                    } else {
                        respCode = "-1";
                        respInfo = tmpSbMsg.toString();
                        break;
                    }
                } else {
                    respCode = "-1";
                    respInfo = retStrArr[1];
                    break;
                }
                WriteBankLogLn("实际查询数：" + respNum);
            }
            WriteBankLogLn("总查询数：" + totalNum + "；实际查询数：" + respNum);
        }
        if ("-1".equals(respCode)) {
            retAts = new RetAtsB001OperBillQry(query.reqHeader);
            retAts.respCode = "-1";
            retAts.respInfo = respInfo;
            retAts.writeBefore();
        }
        retAts.writeEnd();
        return retAts;
    }

    @Override
//    可操作票据查询 b2e0102
    public RetAtsB001OperBillQry D_OperBill_Query_Req(ReqB001OperBillQry query) throws Exception {
        return getBankConfig().getValueAsBool("B001QueryWithMultiThread") ==true ? D_OperBill_Thread(query) : singleThreadQuery(query);
    }

    public String getTransferflg(String actNum, String billNo, String busiNo, String queryType) {
        try {
            BOC01Header bankHeader = new BOC01Header();
            bankHeader.trncod = "b2e0103";//交易代码
            bankHeader.trnid = getQryTransID();//报文编号 字母数字串 0-12位
            XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
            writeCommonHeader(xmlWriter, bankHeader);
//            <trn-b2e0103rq>			交易请求
            xmlWriter.writeStartElement("trn-b2e0103rq");
//                    < b2e0103-rq>		请求内容(1)	不超过1笔	不超过1笔
            xmlWriter.writeStartElement("b2e0103-rq");
//            <ibknum>	联行号	可空5位数字	可空5位数字
            xmlWriter.writeElementString("ibknum", "");
//            <actacn>	账号	可空0-32位数码	非空1-32位数码
            xmlWriter.writeElementString("actacn", actNum);
//                    <querytype>	查询业务种类	非空2-3位数码	I1:票据查询
            xmlWriter.writeElementString("querytype", queryType);
//                    <draftno>	票据号码	可空数码0-
            xmlWriter.writeElementString("draftno", billNo);
//                    <msgseq>	票据标识号	可空0-35位数码	当查询类别为以下类别时：
            xmlWriter.writeElementString("msgseq", busiNo);
//            <cliorg>	组织机构代码	可空字符0-
            xmlWriter.writeElementString("cliorg", "");
            xmlWriter.writeEndDocument();
            boolean isNeedWait = isNeedWaitFiveS();
            if (isNeedWait) {
                if (bankFront.lastVisitTime != null) {
                    long timeSpan = -bankFront.lastVisitTime.getTime() + new Date().getTime();
                    if (timeSpan < 5000l) {
                        long sleepMils = 5000l - timeSpan;
                        this.WriteBankLogLn2("sleep(" + sleepMils + ")");
                        Thread.sleep(5000l - timeSpan);
                    }
                }
            }
            String[] retStrArr = sendToBank(xmlWriter.toXmlString());
            if (retStrArr[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(retStrArr[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String tmpRetCode = tmpBkReader.getFirstText("/bocb2e/trans/trn-b2e0103-rs/status/rspcod");
                    String tmpRetInfo = tmpBkReader.getFirstText("/bocb2e/trans/trn-b2e0103-rs/status/rspmsg");
                    if (isActiveRetCode(tmpRetCode)) {
                        if (tmpBkReader.read("/bocb2e/trans/trn-b2e0103-rs/b2e0103-rs")) {
                            String EachRespCode = tmpBkReader.readedXElement.getSingleText("status/rspcod");
                            String EachRespInfo = tmpBkReader.readedXElement.getSingleText("status/rspmsg");
                            if (bankRetRightCode.equals(EachRespCode)) {
                                if ("A8".equals(queryType)) {
                                    return tmpBkReader.readedXElement.getSingleText("transferflg");
                                } else if ("E3".equals(queryType)) {
                                    return tmpBkReader.readedXElement.getSingleText("endorseinfo/edcflg");
                                }
                            }
                        }
                    }
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            WriteBankLogLn("票据【" + billNo + "】关于查询交易类型【" + billNo + "】的明细失败!");
        }
        return null;
    }

    @Override
//    票据操作明细查询 b2e0287

    public RetAtsB002BillTransQry D_B002_BillTrans_Query(ReqB002BillTransQry query) throws Exception {
        RetAtsB002BillTransQry retAts = new RetAtsB002BillTransQry(query.reqHeader);
        retAts.writeStart();

        BOC01Header bankHeader = new BOC01Header();
        bankHeader.trncod = "b2e0287";//交易代码
        bankHeader.trnid = getQryTransID();//报文编号 字母数字串 0-12位
        XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象

        writeCommonHeader(xmlWriter, bankHeader);
        xmlWriter.writeStartElement("trn-b2e0287-rq");
        xmlWriter.writeStartElement("b2e0287-rq");
        xmlWriter.writeStartElement("account");
        xmlWriter.writeElementString("ibknum", "");
        xmlWriter.writeElementString("actacn", query.actNum);
        xmlWriter.writeEndElement();
        xmlWriter.writeElementString("draftno", query.billNo);
        xmlWriter.writeElementString("begnum", "1");
        xmlWriter.writeElementString("recnum", "50");

        xmlWriter.writeEndDocument();
        //是否需要和前一次请求保持5秒的间隔
        boolean isNeedWait = isNeedWaitFiveS();
        if (isNeedWait) {
            if (bankFront.lastVisitTime != null) {
                long timeSpan = -bankFront.lastVisitTime.getTime() + new Date().getTime();
                if (timeSpan < 5000l) {
                    long sleepMils = 5000l - timeSpan;
                    this.WriteBankLogLn2("sleep(" + sleepMils + ")");
                    Thread.sleep(5000l - timeSpan);
                }
            }
        }


        String[] retStrArr = sendToBank(xmlWriter.toXmlString());

        if (retStrArr[0].length() == 0) {
            StringBuilder tmpSbMsg = new StringBuilder();
            XmlTextReader tmpBkReader = loadBankRespXmlReader(retStrArr[1], tmpSbMsg);
            if (tmpBkReader != null) {
                String tmpRetCode = tmpBkReader.getFirstText("/trn-b2e0287-rs/status/rspcod");
                String tmpRetInfo = tmpBkReader.getFirstText("/trn-b2e0287-rs/status/rspmsg");
                String TotalPage = tmpBkReader.getFirstText("/trn-b2e0287-rs/totalnum");
                int page = Integer.parseInt(TotalPage);
                if (isActiveRetCode(tmpRetCode)) {
                    RetAtsB002BillTransQryDetail detail = new RetAtsB002BillTransQryDetail();
                    while (tmpBkReader.read("trn-b2e0287-rs/b2e0287-rs")) {
                        String EachRespCode = tmpBkReader.readedXElement.getSingleText("/status/rspcod");
                        String EachRespInfo = tmpBkReader.readedXElement.getSingleText("/status/rspmsg");
                        if ("".equals(EachRespCode)) {    //返回码未确定
                            String QueryType = tmpBkReader.getSimpleText("/transtype");
                            QueryType = ConvertQueryType(QueryType);
                            detail.busiType = QueryType;
                            detail.queryType = "1"; //默认申请
                            detail.applyName = tmpBkReader.getSimpleText("/applyname");
                            detail.receName = tmpBkReader.getSimpleText("/signame");
                            detail.overDueRea = tmpBkReader.getSimpleText("/overduereason");
                            detail.transFlag = tmpBkReader.getSimpleText("/transferflg");
                            detail.applyDate = tmpBkReader.getSimpleText("/reqdat");
                            detail.repDueDate = tmpBkReader.getSimpleText("/duedat");
                            retAts.writeDetail(detail);
                        }
                    }
                } else {
                    retAts.writeRespCode("-1");
                    retAts.writeRespInfo(tmpRetInfo);
                }
            } else {
                retAts.writeRespCode("-1");
                retAts.writeRespInfo(tmpSbMsg.toString());
            }
        } else {
            retAts.writeRespCode("-1");
            retAts.writeRespInfo(retStrArr[1]);
        }


        retAts.writeEnd();
        return retAts;
    }

    @Override
//    b2e0103
    public RetAtsB004BillFrontQry D_B004_BillFront_Query(ReqB004BillFrontQry query) throws Exception {
        RetAtsB004BillFrontQry retAts = new RetAtsB004BillFrontQry(query.reqHeader);
        retAts.writeStart();
        BOC01Header bankHeader = new BOC01Header();

        bankHeader.trncod = "b2e0103";//交易代码
        bankHeader.trnid = getQryTransID();//报文编号 字母数字串 0-12位
        XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象

        writeCommonHeader(xmlWriter, bankHeader);
        query.readRecord();
        xmlWriter.writeStartElement("trn-b2e0103-rq");
        xmlWriter.writeStartElement("b2e0103-rq");
        xmlWriter.writeElementString("ibknum", "");
        xmlWriter.writeElementString("actacn", query.detail.actNum);
        String queryType = getQueryType(query.detail.busiType, query.detail.queryType);
        xmlWriter.writeElementString("querytype", queryType);
//        xmlWriter.writeElementString("querytype","I1");
        xmlWriter.writeElementString("draftno", query.detail.billNo);
        xmlWriter.writeElementString("msgseq", query.detail.busiNo);
        xmlWriter.writeElementString("cliorg", "");
        xmlWriter.writeEndDocument();

        //是否需要和前一次请求保持5秒的间隔
        boolean isNeedWait = isNeedWaitFiveS();
        if (isNeedWait) {
            if (bankFront.lastVisitTime != null) {
                long timeSpan = -bankFront.lastVisitTime.getTime() + new Date().getTime();
                if (timeSpan < 5000l) {
                    long sleepMils = 5000l - timeSpan;
                    this.WriteBankLogLn2("sleep(" + sleepMils + ")");
                    Thread.sleep(5000l - timeSpan);
                }
            }
        }

        String[] retStrArr = sendToBank(xmlWriter.toXmlString());

        if (retStrArr[0].length() == 0) {
            StringBuilder tmpSbMsg = new StringBuilder();
            XmlTextReader tmpBkReader = loadBankRespXmlReader(retStrArr[1], tmpSbMsg);
            if (tmpBkReader != null) {
                String tmpRetCode = tmpBkReader.getSimpleText("rspcod");
                String tmpRetInfo = tmpBkReader.getSimpleText("rspmsg");
                String obssid = tmpBkReader.getSimpleText("obssid");
                if (isActiveRetCode(tmpRetCode)) {
                    if (tmpBkReader.read("/bocb2e/trans/trn-b2e0103-rs/b2e0103-rs")) {
                        String EachRespCode = tmpBkReader.readedXElement.getSingleText("status/rspcod");
                        String EachRespInfo = tmpBkReader.readedXElement.getSingleText("status/rspmsg");
                        if (bankRetRightCode.equals(EachRespCode)) {    //返回码未确定
                            retAts.respCode = "0";
                            retAts.respInfo = EachRespInfo;
                            retAts.billType = "AC01".equals(tmpBkReader.readedXElement.getSingleText("drafttype")) ? "1" : "2";
                            retAts.transFlag = "EM00".equals(tmpBkReader.readedXElement.getSingleText("transferflg")) ? "1" : "0";
                            retAts.billNo = tmpBkReader.readedXElement.getSingleText("draftno");
                            retAts.billAmt = tmpBkReader.readedXElement.getSingleText("amount");

                            retAts.drawAct = tmpBkReader.readedXElement.getSingleText("drawee/actacn");
                            retAts.drawName = tmpBkReader.readedXElement.getSingleText("drawee/actnam");
                            retAts.drawCode = tmpBkReader.readedXElement.getSingleText("drawee/orgcde");
                            retAts.drawBnkCode = tmpBkReader.readedXElement.getSingleText("drawee/ibknum");
                            retAts.drawBnkName = tmpBkReader.readedXElement.getSingleText("drawee/bknm");
                            retAts.creditLv = tmpBkReader.readedXElement.getSingleText("drawee/rank");
                            retAts.gradeAgent = tmpBkReader.readedXElement.getSingleText("drawee/rankorg");
                            String rankdate = tmpBkReader.readedXElement.getSingleText("rankdate");
                            if (StringHelper.hasAnyChar(rankdate)) {
                                retAts.gradeDueDate = DateHelper.convertD8toD10(rankdate);
                            }

                            //承兑人
                            retAts.accpName = tmpBkReader.readedXElement.getSingleText("acceptor/actnam");
                            retAts.accpAct = tmpBkReader.readedXElement.getSingleText("acceptor/actacn");
                            retAts.accpBnkCode = tmpBkReader.readedXElement.getSingleText("acceptor/ibknum");
                            retAts.accpBnkName = tmpBkReader.readedXElement.getSingleText("acceptor/bknm");

                            //收票人
                            retAts.payeeName = tmpBkReader.readedXElement.getSingleText("toactn/actnam");
                            retAts.payeeAct = tmpBkReader.readedXElement.getSingleText("toactn/actacn");
                            retAts.payeeBnkCode = tmpBkReader.readedXElement.getSingleText("toactn/ibknum");
                            retAts.payeeBnkName = tmpBkReader.readedXElement.getSingleText("toactn/bknm");

                            String billState = tmpBkReader.readedXElement.getSingleTextByIndex("status", 1);
                            retAts.billState = "-".equals(billState) ? "" : billState;
                            //
                            retAts.issDate = DateHelper.convertD8toD10(tmpBkReader.readedXElement.getSingleText("date"));
                            retAts.dueDate = DateHelper.convertD8toD10(tmpBkReader.readedXElement.getSingleText("duedate"));
                            String guarDate = tmpBkReader.readedXElement.getSingleText("acceptinfo/acpdat");
                            if (StringHelper.hasAnyChar(guarDate)) {
                                retAts.apGuarDate = DateHelper.convertD8toD10(guarDate);
                            }
                            String mustPay = tmpBkReader.readedXElement.getSingleText("consignflag");
                            if (StringHelper.hasAnyChar(mustPay)) {
                                retAts.mustPay = "CC00".equals(mustPay) ? "1" : "0";
                            }
                        } else {
                            retAts.respCode = "-1";
                            retAts.respInfo = EachRespInfo;
                        }
                    } else {
                        retAts.respCode = "-1";
                        retAts.respInfo = "xml格式有误，获取票据信息节点失败";
                    }
                } else {
                    retAts.writeRespCode("-1");
                    retAts.writeRespInfo(tmpRetInfo);
                }
            } else {
                retAts.writeRespCode("-1");
                retAts.writeRespInfo(tmpSbMsg.toString());
            }
        } else {
            retAts.writeRespCode("-1");
            retAts.writeRespInfo(retStrArr[1]);
        }
        retAts.writeRetDetail();
        retAts.writeEnd();
        return retAts;
    }

    @Override
//    b2e0287 背面信息查询
    public RetAtsB005BillBackQry D_B005_BillBack_Query(ReqB005BillBackQry query) throws Exception {
        RetAtsB005BillBackQry retAts = new RetAtsB005BillBackQry(query.reqHeader);
        retAts.writeStart();
        Stack<RetAtsB005BillBackQryDetail> backInfoStack = new Stack<RetAtsB005BillBackQryDetail>();
        BOC01Header bankHeader = new BOC01Header();

        bankHeader.trncod = "b2e0287";//交易代码
        bankHeader.trnid = getQryTransID();//报文编号 字母数字串 0-12位
        XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象

        writeCommonHeader(xmlWriter, bankHeader);
        query.readRecord();
        xmlWriter.writeStartElement("trn-b2e0287-rq");
        xmlWriter.writeStartElement("b2e0287-rq");
        xmlWriter.writeStartElement("account");
        xmlWriter.writeElementString("ibknum", "");
        String actNum = query.detail.actNum;
        String billNo = query.detail.billNo;
        xmlWriter.writeElementString("actacn", actNum);
        xmlWriter.writeEndElement();
        xmlWriter.writeElementString("draftno", billNo);
        xmlWriter.writeElementString("begnum", "1");
        xmlWriter.writeElementString("recnum", "50");
        xmlWriter.writeEndDocument();

        //是否需要和前一次请求保持5秒的间隔
        boolean isNeedWait = isNeedWaitFiveS();
        if (isNeedWait) {
            if (bankFront.lastVisitTime != null) {
                long timeSpan = -bankFront.lastVisitTime.getTime() + new Date().getTime();
                if (timeSpan < 5000l) {
                    long sleepMils = 5000l - timeSpan;
                    this.WriteBankLogLn2("sleep(" + sleepMils + ")");
                    Thread.sleep(5000l - timeSpan);
                }
            }
        }

        String[] retStrArr = sendToBank(xmlWriter.toXmlString());
        if (retStrArr[0].length() == 0) {
            StringBuilder tmpSbMsg = new StringBuilder();
            XmlTextReader tmpBkReader = loadBankRespXmlReader(retStrArr[1], tmpSbMsg);
            if (tmpBkReader != null) {
                String tmpRetCode = tmpBkReader.getSimpleText("rspcod");
                String tmpRetInfo = tmpBkReader.getSimpleText("rspmsg");
                String totalPage = tmpBkReader.getSimpleText("totalnum");
                int page = -1;
                if (!StringHelper.isNullOrEmpty(totalPage)) {
                    page = Integer.parseInt(totalPage);
                }
                int count = 0;
                if (isActiveRetCode(tmpRetCode)) {
                    while (tmpBkReader.read("/bocb2e/trans/trn-b2e0287-rs/b2e0287-rs")) {
                        String EachRespCode = tmpBkReader.readedXElement.getSingleText("status/rspcod");
                        String EachRespInfo = tmpBkReader.readedXElement.getSingleText("status/rspmsg");
                        if (bankRetRightCode.equals(EachRespCode)) {
                            count++;
                            RetAtsB005BillBackQryDetail detail = new RetAtsB005BillBackQryDetail();
                            detail.transCode = transCodeToATS(tmpBkReader.readedXElement.getSingleText("transtype"));
                            detail.respCode = "0";
                            detail.respInfo = EachRespInfo;
                            detail.applyName = tmpBkReader.readedXElement.getSingleText("applyname");
                            detail.receName = tmpBkReader.readedXElement.getSingleText("signame");
                            detail.applyDate = tmpBkReader.readedXElement.getSingleText("reqdat");
                            detail.billNo = billNo;
                            detail.transFlag = "EM00".equals(tmpBkReader.readedXElement.getSingleText("transferflg")) ? "1" : "0";
                            detail.guarAddr = "";
                            if (tmpBkReader.readedXElement.getSingleText("opndat") != null && tmpBkReader.readedXElement.getSingleText("opndat") != "") {
                                detail.repOpenDate = Format.DateTimeFormat.format(Format.Date8Format.parse(tmpBkReader.readedXElement.getSingleText("opndat")));
                            } else {
                                detail.repOpenDate = "";
                            }
                            if (tmpBkReader.readedXElement.getSingleText("duedat") != null && tmpBkReader.readedXElement.getSingleText("duedat") != "") {
                                detail.repDueDate = Format.DateTimeFormat.format(Format.Date8Format.parse(tmpBkReader.readedXElement.getSingleText("duedat")));
                            } else {
                                detail.repDueDate = "";
                            }
                            detail.respFlag = tmpBkReader.readedXElement.getSingleText("1");
                            detail.unPayCode = "";
                            detail.recourseType = "";
//                            retAts.writeDetail(detail);
                            backInfoStack.push(detail);

                            if (count == page || count == 50) {
                                retAts.writeRespCode("0");
                                retAts.writeRespInfo("");
                            }
                        } else {
                            retAts.writeRespCode("0");
                            retAts.writeRespInfo(EachRespInfo);
                            break;
                        }
                    }
                    if (!StringHelper.isNullOrEmpty(totalPage) && Integer.parseInt(totalPage) > 50) {
                        int pageNum = Integer.parseInt(totalPage) / 50 + (Integer.parseInt(totalPage) % 50 == 0 ? 0 : 1);
                        for (int i = 2; i <= pageNum; i++) {
                            retAts = queryForBack(retAts, i, billNo, actNum, backInfoStack);
                        }
                    }
                    while (!backInfoStack.empty()) {
                        retAts.writeDetail(backInfoStack.pop());
                    }
                } else {
                    retAts.writeRespCode("-1");
                    retAts.writeRespInfo(tmpRetInfo);
                }
            } else {
                retAts.writeRespCode("-1");
                retAts.writeRespInfo(tmpSbMsg.toString());
            }
        } else {
            retAts.writeRespCode("-1");
            retAts.writeRespInfo(retStrArr[1]);
        }
        retAts.writeEnd();
        return retAts;
    }

    @Override
    public RetAtsB006BillStateQry D_B006_BillState_Qeury(ReqB006BillStateQry query) throws Exception {
        return b006ForOther(query);
    }

    public RetAtsB006BillStateQry b006ForOther(ReqB006BillStateQry query) {
        RetAtsB006BillStateQry retAts = new RetAtsB006BillStateQry(query.reqHeader);
        retAts.writeStart();
        String billType = "";
        try {
            BOC01Header bankHeader = new BOC01Header();
            bankHeader.trncod = "b2e0529";//交易代码
            bankHeader.trnid = getQryTransID();//报文编号 字母数字串 0-12位
            XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
            query.readRecord();
            String actNum = query.detail.actNum;
            String reqSeqID = query.detail.reqSeqID;
            writeCommonHeader(xmlWriter, bankHeader);
            xmlWriter.writeStartElement("trn-b2e0529-rq");
            xmlWriter.writeStartElement("b2e0529-rq");
            xmlWriter.writeElementString("ibknum", "");
            xmlWriter.writeElementString("actacn", actNum);
            xmlWriter.writeElementString("draftno", "");
            //获取流水
            String obssid = "";
            billType = query.detail.billType;
            String path = trimEndFileSp(getBankConfig().getValueAsString("obssidPath"));
            File allFile = new File(path);
            File[] files = allFile.listFiles();
            for (File f : files) {
                if (f.getName().contains(reqSeqID)) {
                    obssid = f.getName().split("_")[1];
                }
            }
            if (StringHelper.isNullOrEmpty(obssid) && "1".equals(query.detail.operType) &&
                    "1".equals(query.detail.busiType)) {
                obssid = queryObssid(query.detail.reqSeqID);
            }
            xmlWriter.writeElementString("obssid", obssid);

            xmlWriter.writeEndDocument();
            boolean isquick = false;
            int standardMils = getBankConfig().getValueAsInt("EleQueryTimeInterval") == -1 ? 120 : getBankConfig().getValueAsInt("EleQueryTimeInterval");
            long standardTime = standardMils * 1000l;
            long goTime = 0l;
            if (StringHelper.hasAnyChar(query.detail.operateDate)) {
                Date operDate = Format.DateTime21Format.parse(query.detail.operateDate);
                goTime = -operDate.getTime() + new Date().getTime();
                //过两分钟之后再去查询结果
                if (goTime < standardTime) {
                    isquick = true;
                }
            }
            //是否需要和前一次请求保持5秒的间隔
            boolean isNeedWait = isNeedWaitFiveS();
            if (isNeedWait) {
                if (bankFront.lastVisitTime != null) {
                    long timeSpan = -bankFront.lastVisitTime.getTime() + new Date().getTime();
                    if (timeSpan < 5000l) {
                        long sleepMils = 5000l - timeSpan;
                        this.WriteBankLogLn2("sleep(" + sleepMils + ")");
                        Thread.sleep(5000l - timeSpan);
                    }
                }
            }
            String[] retStrArr = sendToBank(xmlWriter.toXmlString());
            if (retStrArr[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(retStrArr[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String tmpRetCode = tmpBkReader.getSimpleText("rspcod");
                    String tmpRetInfo = tmpBkReader.getSimpleText("rspmsg");
                    if (isActiveRetCode(tmpRetCode)) {
                        retAts.writeRespCode("0");
                        retAts.writeRespInfo("");
                        String EachRespCode = tmpBkReader.getFirstText("/bocb2e/trans/trn-b2e0529-rs/b2e0529-rs/status/rspcod");
                        String EachRespInfo = tmpBkReader.getFirstText("/bocb2e/trans/trn-b2e0529-rs/b2e0529-rs/status/rspmsg");
                        String rsltreason = tmpBkReader.getFirstText("/bocb2e/trans/trn-b2e0529-rs/b2e0529-rs/rsltreason");
                        RetAtsB006BillStateQryDetail detail = new RetAtsB006BillStateQryDetail();
                        tmpBkReader.read("/bocb2e/trans/trn-b2e0529-rs/b2e0529-rs");
                        String billNo = tmpBkReader.readedXElement.getSingleText("draftno");
                        String msgseq = tmpBkReader.readedXElement.getSingleText("msgseq");
                        String status = tmpBkReader.readedXElement.getSingleTextByIndex("status", 1);
                        {
                            //返回码未确定
                            if (bankRetRightCode.equals(tmpRetCode)) {
                                if (isquick && "B999".equals(EachRespCode)) {
                                    long sleepMils = standardTime - goTime;
//                    WriteBankLogLn2("sleep("+ sleepMils +")");
                                    String msg = "银行需要2分钟的处理时间，请在：" + sleepMils / 1000 + " 秒后查询！";
                                    detail.respCode = "0";
                                    detail.respInfo = msg;
                                    detail.transState = "B054";
                                    detail.payInfoCode = msg;
                                    retAts.writeDetail(detail);
                                    retAts.writeEnd();
                                    return retAts;
                                }
                                detail.respCode = "0";
                                detail.respInfo = StringHelper.hasAnyChar(rsltreason) ? rsltreason : EachRespInfo;
                                detail.transState = EachRespCode;
                                detail.payInfoCode = EachRespCode;
                                detail.reqSeqID = reqSeqID;
                                WriteBankLogLn("billNO:" + billNo);
                                detail.billNo = billNo;
                                String billState = getBillStatus3(query, billNo, msgseq);
                                detail.billState = "-".equals(billState) ? "" : billState;
                                padBillState("B001", detail, query);
                                retAts.writeDetail(detail);
                            } else {
                                detail.respCode = EachRespCode;
                                detail.respInfo = EachRespInfo;
                                detail.transState = tmpRetCode;
                                detail.payInfoCode = tmpRetCode;
                                detail.reqSeqID = reqSeqID;
                                retAts.writeDetail(detail);
                            }
                        }
                    } else {
                        retAts.writeRespCode("-1");
                        retAts.writeRespInfo(tmpRetInfo);
                    }
                } else {
                    retAts.writeRespCode("-1");
                    retAts.writeRespInfo(tmpSbMsg.toString());
                }
            } else {
                retAts.writeRespCode("-1");
                retAts.writeRespInfo(retStrArr[1]);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        retAts.writeEnd();
        return retAts;
    }

    //当交易完成之后由于权利人发生变化，导致票据状态无法查回，需要dsp自己填充
    private void padBillState(RetAtsB006BillStateQryDetail detail, ReqB006BillStateQry query) {
        if (StringHelper.isNullOrEmpty(detail.billState)) {
            //对方已签收
            if ("B001".equals(detail.transState)) {
                if ("4".equals(query.detail.operType) && "1".equals(query.detail.busiType)) {  //退票
                    detail.billState = "000002";    //结束已作废
                    WriteBankLogLn("由于银行没有返回票据状态：根据撤票业务和交易成功填充票据状态【000002】结束已作废");
                } else if ("1".equals(query.detail.operType) && "3".equals(query.detail.busiType)) {//提示收票
                    detail.billState = "030006";//提示收票已签收
                    WriteBankLogLn("由于银行没有返回票据状态：根据提示收票业务和交易成功填充票据状态【030006】提示收票已签收");
                } else if ("1".equals(query.detail.operType) && "4".equals(query.detail.busiType)) {//背书转让
                    detail.billState = "100006";//背书已签收
                    WriteBankLogLn("由于银行没有返回票据状态：根据背书转让业务和交易成功填充票据状态【100006】背书已签收");
                } else if ("1".equals(query.detail.operType) && "5".equals(query.detail.busiType)) {//质押申请
                    detail.billState = "180006";//质押已签收
                    WriteBankLogLn("由于银行没有返回票据状态：根据质押业务和交易成功填充票据状态【180006】质押已签收");
                } else if ("1".equals(query.detail.operType) && "10".equals(query.detail.busiType)) {//贴现申请
                    if ("1".equals(query.detail.discType)) { //买断式贴现
                        detail.billState = "110106";//买断式贴现已签收
                        WriteBankLogLn("由于银行没有返回票据状态：根据买断式贴现业务和交易成功填充票据状态【110106】买断式贴现已签收");
                    } else if ("2".equals(query.detail.discType)) { //回购式贴现
                        detail.billState = "110206";//回购式贴现已签收
                        WriteBankLogLn("由于银行没有返回票据状态：根据回购式贴现业务和交易成功填充票据状态【110206】回购式贴现已签收");
                    }
                } else if ("1".equals(query.detail.operType) && "12".equals(query.detail.busiType)) {//提示付款申请
                    detail.billState = "000000";    //结束已结清
                    WriteBankLogLn("由于银行没有返回票据状态：根据提示付款业务和交易成功填充票据状态【000000】结束已结清");
                }
            }
        }
    }


    @Override
//  不支持
    public RetAtsB007BillKzsrQry D_B007_BillKzsr_Query(ReqB007BillKzsrQry query) throws Exception {
        RetAtsB007BillKzsrQry retAts = new RetAtsB007BillKzsrQry(query.reqHeader);
        retAts.writeBeforeDetail();
        query.readRecord();
        retAts.respCode = "0";
        retAts.billNo = query.detail.billNo;
        try {
            BOC01Header bankHeader = new BOC01Header();
            bankHeader.trncod = "b2e0102";//交易代码
            bankHeader.trnid = getQryTransID();//报文编号 字母数字串 0-12位
            XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
            String actNum = "";
            writeCommonHeader(xmlWriter, bankHeader);
            xmlWriter.writeStartElement("trn-b2e0102-rq");
            xmlWriter.writeStartElement("b2e0102-rq");
            xmlWriter.writeElementString("ibknum", "");
            actNum = query.detail.actNum;
            xmlWriter.writeElementString("actacn", query.detail.actNum);
            xmlWriter.writeElementString("payeeactn", "");
            xmlWriter.writeElementString("querytype", "H1");
            xmlWriter.writeElementString("acttyp", "");
            xmlWriter.writeElementString("drafttype", "");
            xmlWriter.writeElementString("draweename", "");
            xmlWriter.writeElementString("acceptorname", "");
            xmlWriter.writeElementString("toname", "");
            xmlWriter.writeElementString("draftno", query.detail.billNo);
            xmlWriter.writeStartElement("datescope");
            xmlWriter.writeElementString("from", "");
            xmlWriter.writeElementString("to", "");
            xmlWriter.writeEndElement();
            xmlWriter.writeStartElement("amountscope");
            xmlWriter.writeElementString("from", "");
            xmlWriter.writeElementString("to", "");
            xmlWriter.writeEndElement();
            xmlWriter.writeElementString("begnum", "1");  //页数
            xmlWriter.writeElementString("recnum", "50");//每页内容
            xmlWriter.writeEndDocument();

            //是否需要和前一次请求保持5秒的间隔
            boolean isNeedWait = isNeedWaitFiveS();
            if (isNeedWait) {
                if (bankFront.lastVisitTime != null) {
                    long timeSpan = -bankFront.lastVisitTime.getTime() + new Date().getTime();
                    if (timeSpan < 5000l) {
                        long sleepMils = 5000l - timeSpan;
                        this.WriteBankLogLn2("sleep(" + sleepMils + ")");
                        Thread.sleep(5000l - timeSpan);
                    }
                }
            }
            String[] retStrArr = sendToBank(xmlWriter.toXmlString());

            if (retStrArr[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(retStrArr[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String tmpRetCode = tmpBkReader.getFirstText("/bocb2e/trans/trn-b2e0102-rs/status/rspcod");
                    String tmpRetInfo = tmpBkReader.getFirstText("/bocb2e/trans/trn-b2e0102-rs/status/rspmsg");
                    if (isActiveRetCode(tmpRetCode)) {
                        while (tmpBkReader.read("/bocb2e/trans/trn-b2e0102-rs/b2e0102-rs")) {
                            String EachRespCode = tmpBkReader.readedXElement.getSingleText("status/rspcod");
                            String EachRespInfo = tmpBkReader.readedXElement.getSingleText("status/rspmsg");
                            if (bankRetRightCode.equals(EachRespCode)) {
                                //暂时获取票据的承兑人作为追索人
                                RetAtsB007BillKzsrQryDetail detail = new RetAtsB007BillKzsrQryDetail();
                                // TODO: 2019/4/1
                                //中行暂时不支持获取被追索人的信息，被追索人的组织和开户行等信息需要客户自己填写
                                detail.receName = tmpBkReader.readedXElement.getSingleText("acceptorname");
                                detail.receAct = tmpBkReader.readedXElement.getSingleText("acceptoracn");
                                retAts.writeDetail(detail);
                            }
                        }
                    }
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.getMessage();
        }
        retAts.writeRespInfos();
        retAts.writeEnd();
        return retAts;

    }

    @Override
    public RetAtsB008HistoricalBillQry D_B008_HistoricalBillQuery(ReqB008HistoricalBillQry query) throws Exception {
        RetAtsB008HistoricalBillQry result = new RetAtsB008HistoricalBillQry(reqHeader);
        result.respCode = "-1";
        result.respCode = "DSP未实现接口";
        result.writeBefore();
        result.writeAfter();
        return result;
    }

    @Override
    public RetAtsB009DrawBillQry D_B009_DrawBillQuery(ReqB009DrawBillQry query) throws Exception {
        return null;
    }

    @Override
    public RetAtsB010ProtocolStateQry D_B010_ProtocolStateQuery(ReqB010ProtocolStateQry query) throws Exception {
        return null;
    }

    @Override
    public RetAtsB011TransFlagQry D_B011_TransFlagQuery(ReqB011TransFlagQry query) throws Exception {
        RetAtsB011TransFlagQry retAts = new RetAtsB011TransFlagQry(query.reqHeader);
        retAts.writeStart();
        RetAtsB011TransFlagQryDetail detail = new RetAtsB011TransFlagQryDetail();
        try {
            BOC01Header bankHeader = new BOC01Header();
            bankHeader.trncod = "b2e0103";//交易代码
            bankHeader.trnid = getQryTransID();//报文编号 字母数字串 0-12位
            XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象

            writeCommonHeader(xmlWriter, bankHeader);
            query.readRecord();
            xmlWriter.writeStartElement("trn-b2e0103-rq");
            xmlWriter.writeStartElement("b2e0103-rq");
            xmlWriter.writeElementString("ibknum", "");
            xmlWriter.writeElementString("actacn", query.detail.actNum);
            String queryType = getQueryType(query.detail.busiType, query.detail.queryType);
            xmlWriter.writeElementString("querytype", queryType);
            xmlWriter.writeElementString("draftno", query.detail.billNo);
            xmlWriter.writeElementString("msgseq", query.detail.busiNo);
            xmlWriter.writeElementString("cliorg", "");
            xmlWriter.writeEndDocument();

            //是否需要和前一次请求保持5秒的间隔
            boolean isNeedWait = isNeedWaitFiveS();
            if (isNeedWait) {
                if (bankFront.lastVisitTime != null) {
                    long timeSpan = -bankFront.lastVisitTime.getTime() + new Date().getTime();
                    if (timeSpan < 5000l) {
                        long sleepMils = 5000l - timeSpan;
                        this.WriteBankLogLn2("sleep(" + sleepMils + ")");
                        Thread.sleep(5000l - timeSpan);
                    }
                }
            }
            WriteBankLogStep2(xmlWriter.toXmlString());
            String[] retStrArr = sendToBank(xmlWriter.toXmlString());

            WriteBankLogStep3(retStrArr[1]);
            if (retStrArr[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(retStrArr[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String tmpRetCode = tmpBkReader.getSimpleText("rspcod");
                    String tmpRetInfo = tmpBkReader.getSimpleText("rspmsg");
                    String obssid = tmpBkReader.getSimpleText("obssid");
                    if (isActiveRetCode(tmpRetCode)) {
                        if (tmpBkReader.read("/bocb2e/trans/trn-b2e0103-rs/b2e0103-rs")) {
                            String EachRespCode = tmpBkReader.readedXElement.getSingleText("status/rspcod");
                            String EachRespInfo = tmpBkReader.readedXElement.getSingleText("status/rspmsg");
                            if (bankRetRightCode.equals(EachRespCode)) {    //返回码未确定
                                detail.respCode = "0";
                                detail.respInfo = EachRespInfo;
                                detail.billNo = tmpBkReader.readedXElement.getSingleText("draftno");
                                String transFlag = tmpBkReader.readedXElement.getSingleText("endorseinfo/edcflg");
                                if (StringHelper.hasAnyChar(transFlag)) {
                                    detail.transFlag = "EM00".equals(transFlag) ? "1" : "0";
                                }
                            } else {
                                throw new Exception(EachRespInfo);
                            }
                        } else {
                            throw new Exception("xml格式有误，获取票据信息节点失败");
                        }
                    } else {
                        throw new Exception(tmpRetInfo);
                    }
                } else {
                    throw new Exception(tmpSbMsg.toString());
                }
            } else {
                throw new Exception(retStrArr[1]);
            }
        } catch (Exception ex) {
            detail.respCode = "-1";
            detail.respInfo = ex.getMessage();
            detail.billNo = query.detail.billNo;
        }
        retAts.writeDetail(detail);
        retAts.writeEnd();
        return retAts;
    }


    //    001-提示承兑 002-提示收票 003-背书 004-贴现 005-回购式贴现赎回
//    006-转贴现 007-回购式转贴现赎回 008-再贴现  009-回购式再贴现赎回
//    010-央行卖出商业汇票 011-保证 012-质押013 -质押解除 014-提示付款
//    015-逾期提示付款  016-追索017-撤票
/// 业务类型 1-出票 2-承兑 3-收票 4-背书转让 5-质押 6-解质押 7-出票保证 8-承兑保证 9-背书保证 10-贴现 11-回购式贴现赎回 12-提示付款 13-追索 14-同意清偿
    /// 交易类型代码 2  承兑 3  收票 4  撤票 10  背书转让 11  贴现 12  回购式贴现赎回 13  转贴现 14  回购式转贴现赎回 15  再贴现 16  回购式再贴现赎回 25  央行卖出商业汇票 17  保证 18  质押 19  质押解除 20  提示付款 21  逾期提示付款 22  追索 23  追索同意清偿

    private String ConvertQueryType(String QueryType) throws Exception {
        String BusiType = "";
        if ("001".equals(QueryType)) {
            BusiType = "2";
        } else if ("002".equals(QueryType)) {
            BusiType = "3";
        } else if ("003".equals(QueryType)) {
            BusiType = "10";
        } else if ("004".equals(QueryType)) {
            BusiType = "11";
        } else if ("005".equals(QueryType)) {
            BusiType = "12";
        } else if ("012".equals(QueryType)) {
            BusiType = "18";
        } else if ("013".equals(QueryType)) {
            BusiType = "19";
        } else if ("014".equals(QueryType)) {
            BusiType = "20";
        } else if ("015".equals(QueryType)) {
            BusiType = "21";
        } else if ("016".equals(QueryType)) {
            BusiType = "22";
        } else if ("017".equals(QueryType)) {
            BusiType = "4";
        }

        return BusiType;
    }

    public String getBillStatus(String accountNumber, String billNo, String billType) throws Exception {
        if (StringHelper.isNullOrEmpty(billNo)) {
            return "";
        }
        String retStr = "";
        BOC01Header bankHeader = new BOC01Header();
        bankHeader.trncod = "b2e0102";//交易代码
        bankHeader.trnid = getQryTransID();//报文编号 字母数字串 0-12位
        XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象

        writeCommonHeader(xmlWriter, bankHeader);
        xmlWriter.writeStartElement("trn-b2e0102-rq");
        xmlWriter.writeStartElement("b2e0102-rq");
        xmlWriter.writeElementString("ibknum", "");
        xmlWriter.writeElementString("actacn", accountNumber);
        xmlWriter.writeElementString("payeeactn", "");
        xmlWriter.writeElementString("querytype", "I1");
        xmlWriter.writeElementString("acttyp", "AP01");
        String type = billType.equals("1") ? "AC01" : "AC02";
        xmlWriter.writeElementString("drafttype", type);
        xmlWriter.writeElementString("draweename", "");
        xmlWriter.writeElementString("acceptorname", "");
        xmlWriter.writeElementString("toname", "");
        xmlWriter.writeElementString("draftno", billNo);
        xmlWriter.writeStartElement("datescope");
        xmlWriter.writeElementString("from", "");
        xmlWriter.writeElementString("to", "");
        xmlWriter.writeEndElement();
        xmlWriter.writeStartElement("amountscope");
        xmlWriter.writeElementString("from", "");
        xmlWriter.writeElementString("to", "");
        xmlWriter.writeEndElement();
        xmlWriter.writeElementString("begnum", "");  //页数
        xmlWriter.writeElementString("recnum", "50");//每页内容

        xmlWriter.writeEndDocument();

        //是否需要和前一次请求保持5秒的间隔
        boolean isNeedWait = isNeedWaitFiveS();
        if (isNeedWait) {
            if (bankFront.lastVisitTime != null) {
                long timeSpan = -bankFront.lastVisitTime.getTime() + new Date().getTime();
                if (timeSpan < 5000l) {
                    long sleepMils = 5000l - timeSpan;
                    this.WriteBankLogLn2("sleep(" + sleepMils + ")");
                    Thread.sleep(5000l - timeSpan);
                }
            }
        }
        String[] retStrArr = sendToBank(xmlWriter.toXmlString());

        if (retStrArr[0].length() == 0) {
            StringBuilder tmpSbMsg = new StringBuilder();
            XmlTextReader tmpBkReader = loadBankRespXmlReader(retStrArr[1], tmpSbMsg);
            if (tmpBkReader != null) {
                String tmpRetCode = tmpBkReader.getSimpleText("rspcod");
                String tmpRetInfo = tmpBkReader.getSimpleText("rspmsg");
                if (isActiveRetCode(tmpRetCode)) {
                    while (tmpBkReader.read("/bocb2e/trans/trn-b2e0102-rs/b2e0102-rs")) {
                        retStr = tmpBkReader.readedXElement.getSingleTextByIndex("status", 1);
                    }
                }
            }
        }

        return retStr;
    }

    public String getBillStatus(ReqB006BillStateQry query, String billNo) throws Exception {
        String retStr = "";
        BOC01Header bankHeader = new BOC01Header();
        bankHeader.trncod = "b2e0102";//交易代码
        bankHeader.trnid = getQryTransID();//报文编号 字母数字串 0-12位
        XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象

        writeCommonHeader(xmlWriter, bankHeader);
        xmlWriter.writeStartElement("trn-b2e0102-rq");
        xmlWriter.writeStartElement("b2e0102-rq");
        xmlWriter.writeElementString("ibknum", "");
        xmlWriter.writeElementString("actacn", query.detail.actNum);
        xmlWriter.writeElementString("payeeactn", "");
        String busCode;
        //    业务类型 1-出票 2-承兑 3-收票 4-背书转让 5-质押 6-解质押 7-出票保证 8-承兑保证 9-背书保证 10-贴现 11-回购式贴现赎回 12-提示付款 13-追索 14-同意清偿
        int busiCode = Integer.valueOf(query.detail.busiType);
        if ("1".equals(query.detail.operType)) {
            switch (busiCode) {
                case 1:
                    busCode = "I1";
                    break; //出票
                case 2:
                    busCode = "A2";
                    break;//承兑
                case 3:
                    busCode = "A6";
                    break;//提示收票
                case 4:
                    busCode = "C1";
                    break;//背书
                case 5:
                    busCode = "E2";
                    break;//质押
                case 10:
                    busCode = "D1";
                    break;//贴现
                case 12:
                    busCode = "F2";
                    break;//提示付款
                case 13:
                    busCode = "H2";
                    break;//追索
                case 14:
                    busCode = "H4";
                    break;//清偿
                default: {
                    throw new Exception("位置的申请业务类型：" + query.detail.busiType);
                }
            }
        } else if ("4".equals(query.detail.operType)) {
            switch (busiCode) {
                case 1:
                    busCode = "A5";
                    break; //撤票
                case 2:
                    busCode = "A3";
                    break;//承兑撤销
                case 3:
                    busCode = "A7";
                    break;//提示收票撤销
                case 4:
                    busCode = "C2";
                    break;//背书撤销
                case 5:
                    busCode = "E2";
                    break;//质押撤销
                case 10:
                    busCode = "D2";
                    break;//贴现撤销
                case 12:
                    busCode = "F2";
                    break;//提示付款撤销
                case 13:
                    busCode = "H2";
                    break;//追索撤销
                case 14:
                    busCode = "H4";
                    break;//清偿撤销
                default: {
                    throw new Exception("未知的撤票业务类型：" + query.detail.busiType);
                }
            }

        } else {
            switch (busiCode) {
                case 2:
                    busCode = "A4";
                    break;
                case 4:
                    busCode = "C3";
                    break; //背书签收
                case 6:
                    busCode = "E6";
                    break;//质解签收
                case 11:
                    busCode = "A7";
                    break;//贴现赎回
                case 3:
                    busCode = "A8";
                    break;//提示收票
                case 14:
                    busCode = "H5";
                    break;//同意清偿签收
                default: {
                    throw new Exception("未知的签收业务类型");
                }
            }
        }
        xmlWriter.writeElementString("querytype", busCode);
        if ("I1".equals(busCode)) {
            xmlWriter.writeElementString("acttyp", "AP01");
        } else {
            xmlWriter.writeElementString("acttyp", "");
        }
        String type = "1".equals(query.detail.billType) ? "AC01" : "AC02";
        xmlWriter.writeElementString("drafttype", type);
        xmlWriter.writeElementString("draweename", "");
        xmlWriter.writeElementString("acceptorname", "");
        xmlWriter.writeElementString("toname", "");
        xmlWriter.writeElementString("draftno", StringHelper.hasAnyChar(billNo) ? billNo : query.detail.billNo);
        xmlWriter.writeStartElement("datescope");
        xmlWriter.writeElementString("from", "");
        xmlWriter.writeElementString("to", "");
        xmlWriter.writeEndElement();
        xmlWriter.writeStartElement("amountscope");
        xmlWriter.writeElementString("from", "");
        xmlWriter.writeElementString("to", "");
        xmlWriter.writeEndElement();
        xmlWriter.writeElementString("begnum", "");  //页数
        xmlWriter.writeElementString("recnum", "50");//每页内容

        xmlWriter.writeEndDocument();
        //是否需要和前一次请求保持5秒的间隔
        boolean isNeedWait = isNeedWaitFiveS();
        if (isNeedWait) {
            if (bankFront.lastVisitTime != null) {
                long timeSpan = -bankFront.lastVisitTime.getTime() + new Date().getTime();
                if (timeSpan < 5000l) {
                    long sleepMils = 5000l - timeSpan;
                    this.WriteBankLogLn2("sleep(" + sleepMils + ")");
                    Thread.sleep(5000l - timeSpan);
                }
            }
        }
        String[] retStrArr = sendToBank(xmlWriter.toXmlString());

        if (retStrArr[0].length() == 0) {
            StringBuilder tmpSbMsg = new StringBuilder();
            XmlTextReader tmpBkReader = loadBankRespXmlReader(retStrArr[1], tmpSbMsg);
            if (tmpBkReader != null) {
                String tmpRetCode = tmpBkReader.getSimpleText("rspcod");
                String tmpRetInfo = tmpBkReader.getSimpleText("rspmsg");
                if (isActiveRetCode(tmpRetCode)) {
                    while (tmpBkReader.read("/bocb2e/trans/trn-b2e0102-rs/b2e0102-rs")) {
                        retStr = tmpBkReader.readedXElement.getSingleTextByIndex("status", 1);
                    }
                }
            }
        }

        return retStr;
    }

    public String getBillStatus3(ReqB006BillStateQry query, String billNo, String msgseq) throws Exception {
        String retStr = "";
        BOC01Header bankHeader = new BOC01Header();
        bankHeader.trncod = "b2e0103";//交易代码
        bankHeader.trnid = getQryTransID();//报文编号 字母数字串 0-12位
        XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象

        writeCommonHeader(xmlWriter, bankHeader);
        xmlWriter.writeStartElement("trn-b2e0103-rq");
        xmlWriter.writeStartElement("b2e0103-rq");
        xmlWriter.writeElementString("ibknum", "");
        xmlWriter.writeElementString("actacn", query.detail.actNum);
//        xmlWriter.writeElementString("payeeactn", "");
        String busCode;
        //    业务类型 1-出票 2-承兑 3-收票 4-背书转让 5-质押 6-解质押 7-出票保证 8-承兑保证 9-背书保证 10-贴现 11-回购式贴现赎回 12-提示付款 13-追索 14-同意清偿
        int busiCode = Integer.valueOf(query.detail.busiType);
        if ("1".equals(query.detail.operType)) {
            switch (busiCode) {
                case 1:
                    busCode = "I1";
                    break; //出票
                case 2:
                    busCode = "A2";
                    break;//承兑
                case 3:
                    busCode = "A6";
                    break;//提示收票
                case 4:
                    busCode = "C1";
                    break;//背书
                case 5:
                    busCode = "E1";
                    break;//质押
                case 6:
                    busCode = "E4";
                    break;//质押解除
                case 10:
                    busCode = "D1";
                    break;//贴现
                case 12:
                    busCode = "F1";
                    break;//提示付款
                case 13:
                    busCode = "H1";
                    break;//追索
                case 14:
                    busCode = "H3";
                    break;//清偿
                default: {
                    throw new Exception("位置的申请业务类型：" + query.detail.busiType);
                }
            }
        } else if ("4".equals(query.detail.operType)) {
            switch (busiCode) {
                case 1:
                    busCode = "A5";
                    break; //撤票
                case 2:
                    busCode = "A3";
                    break;//承兑撤销
                case 3:
                    busCode = "A7";
                    break;//提示收票撤销
                case 4:
                    busCode = "C2";
                    break;//背书撤销
                case 5:
                    busCode = "E2";
                    break;//质押撤销
                case 6:
                    busCode = "E5";
                    break;//解质押撤销
                case 10:
                    busCode = "D2";
                    break;//贴现撤销
                case 12:
                    busCode = "F2";
                    break;//提示付款撤销
                case 13:
                    busCode = "H2";
                    break;//追索撤销
                case 14:
                    busCode = "H4";
                    break;//清偿撤销
                default: {
                    throw new Exception("未知的撤票业务类型：" + query.detail.busiType);
                }
            }

        } else {
            switch (busiCode) {
                case 2:
                    busCode = "A4";
                    break;
                case 4:
                    busCode = "C3";
                    break; //背书签收
                case 5:
                    busCode = "E3";
                    break; //质押签收
                case 6:
                    busCode = "E6";
                    break;//质解签收
                case 11:
                    busCode = "";
                    break;//贴现赎回
                case 12:
                    busCode = "G1";
                    break;//提示付款签收
                case 3:
                    busCode = "A8";
                    break;//提示收票
                case 14:
                    busCode = "H5";
                    break;//同意清偿签收
                default: {
                    busCode = "I1";
                }
            }
        }
        xmlWriter.writeElementString("querytype", busCode);
//        xmlWriter.writeElementString("querytype", "I1");
        xmlWriter.writeElementString("draftno", StringHelper.hasAnyChar(billNo) ? billNo : query.detail.billNo);
        xmlWriter.writeElementString("msgseq", msgseq);
        xmlWriter.writeElementString("cliorg", "");

        xmlWriter.writeEndDocument();
        //是否需要和前一次请求保持5秒的间隔
        boolean isNeedWait = isNeedWaitFiveS();
        if (isNeedWait) {
            if (bankFront.lastVisitTime != null) {
                long timeSpan = -bankFront.lastVisitTime.getTime() + new Date().getTime();
                if (timeSpan < 5000l) {
                    long sleepMils = 5000l - timeSpan;
                    this.WriteBankLogLn2("sleep(" + sleepMils + ")");
                    Thread.sleep(5000l - timeSpan);
                }
            }
        }
        String[] retStrArr = sendToBank(xmlWriter.toXmlString());

        if (retStrArr[0].length() == 0) {
            StringBuilder tmpSbMsg = new StringBuilder();
            XmlTextReader tmpBkReader = loadBankRespXmlReader(retStrArr[1], tmpSbMsg);
            if (tmpBkReader != null) {
                String tmpRetCode = tmpBkReader.getSimpleText("rspcod");
                String tmpRetInfo = tmpBkReader.getSimpleText("rspmsg");
                if (isActiveRetCode(tmpRetCode)) {
                    while (tmpBkReader.read("/bocb2e/trans/trn-b2e0103-rs/b2e0103-rs")) {
                        retStr = tmpBkReader.readedXElement.getSingleTextByIndex("status", 1);
                    }
                }
            }
        }

        return retStr;
    }

    public RetAtsB001OperBillQry queryLoop(ReqB001OperBillQry query, int page, RetAtsB001OperBillQry retAts, String queryType, String actNum, String billType) throws Exception {
        BOC01Header bankHeader = new BOC01Header();
        bankHeader.trncod = "b2e0102";//交易代码
        bankHeader.trnid = getQryTransID();//报文编号 字母数字串 0-12位
        XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象

        writeCommonHeader(xmlWriter, bankHeader);
        xmlWriter.writeStartElement("trn-b2e0102-rq");
        xmlWriter.writeStartElement("b2e0102-rq");
        xmlWriter.writeElementString("ibknum", "");
        xmlWriter.writeElementString("actacn", actNum);
        xmlWriter.writeElementString("payeeactn", "");
        xmlWriter.writeElementString("querytype", queryType);
        xmlWriter.writeElementString("acttyp", "");
        xmlWriter.writeElementString("drafttype", billType);
        xmlWriter.writeElementString("draweename", "");
        xmlWriter.writeElementString("acceptorname", "");
        xmlWriter.writeElementString("toname", "");
        xmlWriter.writeElementString("draftno", "");
        xmlWriter.writeStartElement("datescope");
        xmlWriter.writeElementString("from", "");
        xmlWriter.writeElementString("to", "");
        xmlWriter.writeEndElement();
        xmlWriter.writeStartElement("amountscope");
        xmlWriter.writeElementString("from", "");
        xmlWriter.writeElementString("to", "");
        xmlWriter.writeEndElement();
        //起始记录
        xmlWriter.writeElementString("begnum", page + "");
        xmlWriter.writeElementString("recnum", "50");//每页内容
        xmlWriter.writeEndDocument();
        //是否需要和前一次请求保持5秒的间隔
        boolean isNeedWait = isNeedWaitFiveS();
        if (isNeedWait) {
            if (bankFront.lastVisitTime != null) {
                long timeSpan = -bankFront.lastVisitTime.getTime() + new Date().getTime();
                if (timeSpan < 5000l) {
                    long sleepMils = 5000l - timeSpan;
                    this.WriteBankLogLn2("sleep(" + sleepMils + ")");
                    Thread.sleep(5000l - timeSpan);
                }
            }
        }
        String[] retStrArr = sendToBank(xmlWriter.toXmlString());

        if (retStrArr[0].length() == 0) {
            StringBuilder tmpSbMsg = new StringBuilder();
            XmlTextReader tmpBkReader = loadBankRespXmlReader(retStrArr[1], tmpSbMsg);
            if (tmpBkReader != null) {
                String tmpRetCode = tmpBkReader.getFirstText("/bocb2e/trans/trn-b2e0102-rs/status/rspcod");
                String tmpRetInfo = tmpBkReader.getFirstText("/bocb2e/trans/trn-b2e0102-rs/status/rspmsg");
                String totalPage = tmpBkReader.getFirstText("/bocb2e/trans/trn-b2e0102-rs/totalnum");
                if (isActiveRetCode(tmpRetCode)) {
                    RetAtsB001OperBillQryDetail detail = new RetAtsB001OperBillQryDetail();
                    while (tmpBkReader.read("/bocb2e/trans/trn-b2e0102-rs/b2e0102-rs")) {
                        String EachRespCode = tmpBkReader.readedXElement.getSingleText("status/rspcod");
                        String EachRespInfo = tmpBkReader.readedXElement.getSingleText("status/rspmsg");
                        if (bankRetRightCode.equals(EachRespCode)) {
                            detail.drawAct = tmpBkReader.readedXElement.getSingleText("draweeacn");//出票人账号
                            detail.drawName = tmpBkReader.readedXElement.getSingleText("draweename");
                            detail.drawCode = tmpBkReader.readedXElement.getSingleText("cliorg");
                            detail.payeeAct = tmpBkReader.readedXElement.getSingleText("toacn");//收票人账号
                            detail.payeeName = tmpBkReader.readedXElement.getSingleText("toname");
                            detail.accpAct = tmpBkReader.readedXElement.getSingleText("acceptoracn");
                            detail.accpName = tmpBkReader.readedXElement.getSingleText("acceptorname");//承兑人
                            detail.billAmt = tmpBkReader.readedXElement.getSingleText("amount");
                            detail.billNo = tmpBkReader.readedXElement.getSingleText("draftno");
                            detail.issDate = DateHelper.convertD8toD10(tmpBkReader.readedXElement.getSingleText("date"));
                            detail.dueDate = DateHelper.convertD8toD10(tmpBkReader.readedXElement.getSingleText("duedate"));
                            detail.applyName = tmpBkReader.readedXElement.getSingleText("applyname");
                            detail.mustPay = "1";
                            //收票签收
                            if ("A8".equals(queryType) && StringHelper.isNullOrEmpty(detail.applyName)) {
                                detail.applyName = detail.drawName;
                            }
                            detail.discRate = tmpBkReader.readedXElement.getSingleText("rdsrat");
                            detail.recourseAmt = tmpBkReader.readedXElement.getSingleText("tramt");
                            detail.billStatus = tmpBkReader.readedXElement.getSingleTextByIndex("status", 1);
                            detail.billType = "AC01".equals(tmpBkReader.readedXElement.getSingleText("drafttype")) ? "EM001" : "EM002";

                            detail.busiNo = tmpBkReader.readedXElement.getSingleText("msgseq");
                            //提示收票签收和背书签收
                            if ("A8".equals(queryType) || "E3".equals(queryType)) {
                                boolean isQueryTransFlag = getBankConfig().getValueAsBool("isQueryTransFlag");
                                if (isQueryTransFlag) {
                                    String tranFlag = getTransferflg(query.detail.actNum, detail.billNo, detail.busiNo,
                                            queryType);
                                    if (StringHelper.hasAnyChar(tranFlag)) {
                                        detail.transFlag = "EM00".equals(tranFlag) ? "1" : "0";
                                    }
                                }
                            }
                            retAts.writeDetail(detail);

                        }
                    }
                }
            }
        }
        return retAts;
    }

    public RetAtsB005BillBackQry queryForBack(RetAtsB005BillBackQry retAts, int page, String actNum, String billNo, Stack<RetAtsB005BillBackQryDetail> backInfoStack) throws Exception {
        BOC01Header bankHeader = new BOC01Header();

        bankHeader.trncod = "b2e0287";//交易代码
        bankHeader.trnid = getQryTransID();//报文编号 字母数字串 0-12位
        XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象

        writeCommonHeader(xmlWriter, bankHeader);
        xmlWriter.writeStartElement("trn-b2e0287-rq");
        xmlWriter.writeStartElement("b2e0287-rq");
        xmlWriter.writeStartElement("account");
        xmlWriter.writeElementString("ibknum", "");
        xmlWriter.writeElementString("actacn", actNum);
        xmlWriter.writeEndElement();
        xmlWriter.writeElementString("draftno", billNo);
        xmlWriter.writeElementString("begnum", page + "");
        xmlWriter.writeElementString("recnum", "50");
        xmlWriter.writeEndDocument();
        //是否需要和前一次请求保持5秒的间隔
        boolean isNeedWait = isNeedWaitFiveS();
        if (isNeedWait) {
            if (bankFront.lastVisitTime != null) {
                long timeSpan = -bankFront.lastVisitTime.getTime() + new Date().getTime();
                if (timeSpan < 5000l) {
                    long sleepMils = 5000l - timeSpan;
                    this.WriteBankLogLn2("sleep(" + sleepMils + ")");
                    Thread.sleep(5000l - timeSpan);
                }
            }
        }
        String[] retStrArr = sendToBank(xmlWriter.toXmlString());
        if (retStrArr[0].length() == 0) {
            StringBuilder tmpSbMsg = new StringBuilder();
            XmlTextReader tmpBkReader = loadBankRespXmlReader(retStrArr[1], tmpSbMsg);
            if (tmpBkReader != null) {
                String tmpRetCode = tmpBkReader.getSimpleText("rspcod");
                String tmpRetInfo = tmpBkReader.getSimpleText("rspmsg");
                String totalPage = tmpBkReader.getSimpleText("totalnum");
                if (!StringHelper.isNullOrEmpty(totalPage)) {
                    page = Integer.parseInt(totalPage);
                }
                int count = 0;
                if (isActiveRetCode(tmpRetCode)) {
                    while (tmpBkReader.read("/bocb2e/trans/trn-b2e0287-rs/b2e0287-rs")) {
                        String EachRespCode = tmpBkReader.readedXElement.getSingleText("status/rspcod");
                        String EachRespInfo = tmpBkReader.readedXElement.getSingleText("status/rspmsg");
                        if (bankRetRightCode.equals(EachRespCode)) {
                            count++;
                            RetAtsB005BillBackQryDetail detail = new RetAtsB005BillBackQryDetail();
                            detail.transCode = ConvertQueryType(tmpBkReader.readedXElement.getSingleText("transtype"));
                            detail.respCode = EachRespCode;
                            detail.respInfo = EachRespInfo;
                            detail.applyName = tmpBkReader.readedXElement.getSingleText("applyname");
                            detail.receName = tmpBkReader.readedXElement.getSingleText("signame");
                            detail.applyDate = Format.DateTimeFormat.format(Format.Date8Format.parse(tmpBkReader.readedXElement.getSingleText("reqdat")));
                            detail.billNo = billNo;
                            detail.transFlag = "EM00".equals(tmpBkReader.readedXElement.getSingleText("transferflg")) ? "0" : "1";
                            detail.guarAddr = "";
                            detail.repOpenDate = Format.DateTimeFormat.format(Format.Date8Format.parse(tmpBkReader.readedXElement.getSingleText("opndat")));

                            detail.repDueDate = Format.DateTimeFormat.format(Format.Date8Format.parse(tmpBkReader.readedXElement.getSingleText("duedat")));
                            detail.respFlag = tmpBkReader.readedXElement.getSingleText("1");
                            detail.unPayCode = "";
                            detail.recourseType = "";
                            backInfoStack.push(detail);
//                            retAts.writeDetail(detail);
                        }
                    }
                }
            }
        }
        return retAts;
    }

    //    001-提示承兑 002-提示收票 003-背书 004-贴现 005-回购式贴现赎回
//    006-转贴现 007-回购式转贴现赎回 008-再贴现  009-回购式再贴现赎回
//    010-央行卖出商业汇票 011-保证 012-质押013 -质押解除 014-提示付款
//    015-逾期提示付款  016-追索017-撤票

    // 交易类型代码 2  承兑 3  收票 4  撤票 10  背书转让 11  贴现 12  回购式贴现赎回 13  转贴现 14  回购式转贴现赎回 15  再贴现 16  回购式再贴现赎回 25  央行卖出商业汇票 17  保证 18  质押 19  质押解除 20  提示付款 21  逾期提示付款 22  追索 23  追索同意清偿
    private String transCodeToATS(String code) {
        String retCode = "";
        if ("001".equals(code)) {
            retCode = "2";
        }
        if ("002".equals(code)) {
            retCode = "3";
        }
        if ("003".equals(code)) {
            retCode = "10";
        }
        if ("004".equals(code)) {
            retCode = "11";
        }
        if ("005".equals(code)) {
            retCode = "12";
        }
        if ("006".equals(code)) {
            retCode = "13";
        }
        if ("007".equals(code)) {
            retCode = "14";
        }
        if ("008".equals(code)) {
            retCode = "15";
        }
        if ("009".equals(code)) {
            retCode = "16";
        }
        if ("010".equals(code)) {
            retCode = "25";
        }
        if ("011".equals(code)) {
            retCode = "17";
        }
        if ("012".equals(code)) {
            retCode = "18";
        }
        if ("013".equals(code)) {
            retCode = "19";
        }
        if ("014".equals(code)) {
            retCode = "20";
        }
        if ("015".equals(code)) {
            retCode = "21";
        }
        if ("016".equals(code)) {
            retCode = "22";
        }
        if ("017".equals(code)) {
            retCode = "4";
        }
        return retCode;

    }


    private String queryObssid(String insid) throws Exception {
        String obssid = "";
        try {
            BOC01Header bankHeader = new BOC01Header();
            bankHeader.trncod = "b2e0007";//交易代码
            bankHeader.trnid = getQryTransID();//报文编号 字母数字串 0-12位
            XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
            writeCommonHeader(xmlWriter, bankHeader);//写入通用的头部节点
            xmlWriter.writeStartElement("trn-" + bankHeader.trncod + "-rq");
            xmlWriter.writeStartElement(bankHeader.trncod + "-rq");
            xmlWriter.writeElementString("insid", insid);
            xmlWriter.writeElementClosed("obssid");
            xmlWriter.writeEndDocument();
            String[] tmpStrRet = sendToBank(xmlWriter.toXmlString());
            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String tmprspcod = tmpBkReader.getFirstText("/bocb2e/trans/trn-" + bankHeader.trncod + "-rs/status/rspcod");
                    String tmprspmsg = tmpBkReader.getFirstText("/bocb2e/trans/trn-" + bankHeader.trncod + "-rs/status/rspmsg");
                    if (isActiveRetCode(tmprspcod)) {
                        obssid = tmpBkReader.getFirstText("/bocb2e/trans/trn-b2e0007-rs/b2e0007-rs/obssid");
                    }
                } else {
                    throw new Exception(tmpSbMsg.toString());
                }
            } else {
                throw new Exception(tmpStrRet[1]);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return obssid;
    }

}
